import { createContext, useContext } from "react"
import { matchPath, useLocation, useOutlet } from "react-router-dom"
import React from 'react'
interface KeepAliveProps {
    keepPath: string[]
    children: React.ReactNode
}
//用来缓存组件的对象
const keepElments: Record<string, any> = {}
const KeepAliveContext = createContext({
    keepPath: [] as string[],//要缓存的路由地址数组
    keepElments,//缓存的组件的dom结构
    dropByPath(path: string) {
        keepElments[path] = null
    }
})
const isKeepPath = (keepPath: string[], path: string) => {
    return keepPath.includes(path)
}
export default function KeepAlive(props: KeepAliveProps) {
    const { keepPath } = props
    const { keepElments, dropByPath } = useContext(KeepAliveContext)
    return (
        <KeepAliveContext.Provider value={{ keepPath, keepElments, dropByPath }}>
            {props.children}
        </KeepAliveContext.Provider>
    )
}
export function useKeepOutlet() {
    const location = useLocation()
    const element = useOutlet()//获取当前路由的子路由组件的虚拟dom对象
    const { keepElments, keepPath } = useContext(KeepAliveContext)
    const isKeep = isKeepPath(keepPath, location.pathname)//判断路由地址是不是指明要缓存的组件
    if (isKeep) {
        keepElments[location.pathname] = element//将要换成的组件dom结构存到缓存对象中
    }
    return <>
        {
            Object.entries(keepElments).map(([pathname, element]) => {
                return (
                    <div key={pathname} 
                    style={{overflow:"hidden"}}
                    hidden={!matchPath(pathname,location.pathname)}//不匹配则隐藏,实际就是设置了display为none
                    className="keep-alive-page">
                        {element}
                    </div>
                )
            })
        }
        {
            !isKeep&&element
        }
    </>
}
